package com.lst.projectlib.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.zip.GZIPOutputStream;

public class BitmapUtil {
	/**
	 * 获取给定宽高的圆角图片
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap toRoundCorner(Bitmap bitmap, int w, int h,
			int roundPixels) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		// 计算缩放比例
		float scaleWidth = ((float) w) / width;
		float scaleHeight = ((float) h) / height;

		// 取得想要缩放的matrix参数
		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);

		// 得到新的图片
		Bitmap newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix,
				true);

		// 创建一个规定大小位图
		Bitmap roundConcerImage = Bitmap.createBitmap(w, h, Config.ARGB_8888);

		// 创建带有位图roundConcerImage的画布
		Canvas canvas = new Canvas(roundConcerImage);

		// 创建画笔
		Paint paint = new Paint();

		// 去锯齿
		paint.setAntiAlias(true);
		paint.setFilterBitmap(true);

		// 创建一个和canvas一样大小的矩形
		Rect rect = new Rect(0, 0, w, h);
		RectF rectF = new RectF(rect);

		// 画一个和canvas一样大小的圆角矩形
		canvas.drawRoundRect(rectF, roundPixels, roundPixels, paint);

		// 设置相交模式
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
		// 把图片画到矩形去
		canvas.drawBitmap(newbm, null, rect, paint);

		return roundConcerImage;
	}

	/**
	 * 获取正方形的圆角图片
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap toSquareRoundCorner(Bitmap bitmap) {
		return toRoundCorner(bitmap, 100, 100, 15);
	}

	/**
	 * 转换图片成圆形
	 * 
	 * @param bitmap
	 *            传入Bitmap对象
	 * @return
	 */
	public static Bitmap toRoundBitmap(Bitmap bitmap) {
		return toRoundBitmap(bitmap, false);
	}
	
	public static Bitmap toRoundBitmap(Bitmap bitmap, boolean isMengBlackTrans) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		float roundPx;
		float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
		if (width <= height) {
			roundPx = width / 2;

			left = 0;
			top = 0;
			right = width;
			bottom = width;

			height = width;

			dst_left = 0;
			dst_top = 0;
			dst_right = width;
			dst_bottom = width;
		} else {
			roundPx = height / 2;

			float clip = (width - height) / 2;

			left = clip;
			right = width - clip;
			top = 0;
			bottom = height;
			width = height;

			dst_left = 0;
			dst_top = 0;
			dst_right = height;
			dst_bottom = height;
		}

		Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final Paint paint = new Paint();
		final Rect src = new Rect((int) left, (int) top, (int) right,
				(int) bottom);
		final Rect dst = new Rect((int) dst_left, (int) dst_top,
				(int) dst_right, (int) dst_bottom);
		final RectF rectF = new RectF(dst);

		paint.setAntiAlias(true);// 设置画笔无锯齿

		canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas

		// 以下有两种方法画圆,drawRounRect和drawCircle
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// 画圆角矩形，第一个参数为图形显示区域，第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。
		// canvas.drawCircle(roundPx, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 设置两张图片相交时的模式,参考http://trylovecatch.iteye.com/blog/1189452
		canvas.drawBitmap(bitmap, src, dst, paint); // 以Mode.SRC_IN模式合并bitmap和已经draw了的Circle
		
		if (isMengBlackTrans) {
			paint.setColor(Color.argb(180, 0, 0, 0));
			paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));
			canvas.drawRect(new Rect((int) dst_left, (int) dst_top + (int)((dst_bottom - dst_top) * 5f  / 8f),
					(int) dst_right, (int) dst_bottom + (int)((dst_bottom - dst_top) / 4f)), paint);
		}

		return output;
	}

	/**
	 * 图片按质量压缩,该方法在保持像素的前提下改变图片的位深及透明度等
	 *
	 * @param image
	 * @return
	 */
	private static Bitmap compressImageByQuality(Bitmap image, int maxSpace) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
		int options = 90;
		while (baos.toByteArray().length / 1024 > maxSpace) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
			options -= 10;// 每次都减少10
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
		return bitmap;
	}

	/**
	 * 获取SD卡中的图片,原图
	 *
	 * @param filePath
	 * @return
	 */
	public static Bitmap getSDBitmap(String filePath) {
		boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
		if (sdCardExist) {
			File mfile = new File(filePath);
			if (mfile.exists()) {
				Bitmap bm = BitmapFactory.decodeFile(filePath);
				return bm;
			}
		}
		return null;
	}

	/**
	 * 根据图片路径，按大小比例和质量压缩
	 * 
	 * @param srcPath
	 * @return
	 */
	public static Bitmap compressFromPath(String srcPath, int maxWidth, int maxHeight) {
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
		newOpts.inJustDecodeBounds = false;
		// 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
		newOpts.inSampleSize = computeSampleSize(newOpts, -1, maxWidth * maxHeight);// android源码设置缩放比例
		newOpts.inPreferredConfig = Config.RGB_565;

		// 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		return compressImageByQuality(bitmap, 100);// 压缩好比例大小后再进行质量压缩
	}

	/**
	 * 根据图片的Bitmap,按大小比例压缩
	 * 
	 * @param image
	 * @return
	 */
	public static Bitmap compressFromBitmap(Bitmap image, int maxWidth, int maxHeight, int quality) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);

		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		newOpts.inJustDecodeBounds = false;
		newOpts.inSampleSize = computeSampleSize(newOpts, -1, maxWidth * maxHeight);// android源码设置缩放比例
		newOpts.inPreferredConfig = Config.RGB_565;
		// 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		isBm = new ByteArrayInputStream(baos.toByteArray());
		bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		return compressImageByQuality(bitmap, quality);// 压缩好比例大小后再进行质量压缩
	}

	/**
	 * 根据文字，获取drawable
	 * @param text
	 * @param context
	 * @return
	 */
	public static Drawable getIndicatorDrawable(String text, Context context) {
		Paint paint = new Paint();
		paint.setColor(Color.WHITE);
		paint.setStrokeWidth(4);
		paint.setTextSize(14);
		paint.setTypeface(Typeface.DEFAULT_BOLD);
		paint.setTextAlign(Paint.Align.CENTER);

		FontMetrics fm = paint.getFontMetrics();
		int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);

		Bitmap bm = Bitmap.createBitmap(textHeight + 3, textHeight + 3, Config.ARGB_8888);
		Canvas canvas = new Canvas(bm);

		int w = bm.getWidth();
		int h = bm.getHeight();

		canvas.drawARGB(255, 255, 135, 38);
		canvas.drawText(text, w / 2, h / 2 + textHeight / 4, paint);

		BitmapDrawable bd = new BitmapDrawable(context.getResources(), bm);
		return bd;
	}

	/**
	 * 根据文字，获取bitmap
	 * @param text
	 * @param context
     * @return
     */
	public static Bitmap getIndicatorBitmap(String text, Context context) {
		Paint paint = new Paint();
		paint.setColor(Color.WHITE);
		paint.setStrokeWidth(4);
		paint.setTextSize(14);
		paint.setTypeface(Typeface.DEFAULT_BOLD);
		paint.setTextAlign(Paint.Align.CENTER);
		paint.setAntiAlias(true);

		Paint paintOval = new Paint();
		paintOval.setColor(Color.RED);
		paintOval.setAntiAlias(true);

		FontMetrics fm = paint.getFontMetrics();
		int textHeight = (int) (fm.bottom - fm.top);

		int w = getTextWidth(text, paint) + 10;
		int h = getTextHeight(text, paint) + 10;

		Bitmap bm = null;
		Canvas canvas = null;

		if (w <= h) {
			w = h;
			bm = Bitmap.createBitmap(h, h, Config.ARGB_8888);
			canvas = new Canvas(bm);
			canvas.drawCircle(w / 2, h / 2, h / 2, paintOval);
		} else {
			bm = Bitmap.createBitmap(w, h, Config.ARGB_8888);
			canvas = new Canvas(bm);
			RectF oval = new RectF(0, 0, (float) w, (float) h);
			// canvas.drawRoundRect(oval, w, w, paintOval);
			canvas.drawOval(oval, paintOval);
		}

		canvas.drawText(text, w / 2, h / 2 + textHeight / 2 - fm.bottom, paint);
		return bm;
	}

	private static int getTextWidth(String text, Paint paint) {
		Rect bounds = new Rect();
		paint.getTextBounds(text, 0, text.length(), bounds);
		int width = bounds.left + bounds.width();
		return width;
	}

	private static int getTextHeight(String text, Paint paint) {
		Rect bounds = new Rect();
		paint.getTextBounds(text, 0, text.length(), bounds);
		int height = bounds.bottom + bounds.height();
		return height;
	}

	/**
	 * 图片缩略图显示
	 *
	 * @param filePath
	 * @return
	 */
	public static Bitmap createImageThumbnail(String filePath) {
		return compressFromPath(filePath, 128, 128);
	}

	/**
	 * 根据图片路径取出图片并转换成base64
	 * 
	 * @return
	 */
	public static String getBitmapToBase64(String path, int maxWidth, int maxHeight) {
		String byteArry = null;
		try {
			Bitmap bitmap = compressFromPath(path, maxWidth, maxHeight);
			// 读取图片输入流
			ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream);
			// 将流转化成字节数组
			byteStream.flush();
			byteStream.close();
			byte[] imgBytes = byteStream.toByteArray();
			byteArry = Base64.encodeToString(imgBytes, Base64.DEFAULT);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return byteArry;
	}

	/**
	 * 根据图片路径取出图片并转换成string字符串,不用base64,用Gzip压缩
	 * 
	 * @return
	 */
	public static String getBitmapToGZipString(String path, int maxWidth, int maxHeight) {

		String byteArry = null;
		try {
			Bitmap bitmap = compressFromPath(path, maxWidth, maxHeight);
			// 读取图片输入流
			ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream);
			// 将流转化成字节数组
			byteStream.flush();
			byteStream.close();
			byte[] imgBytes = byteStream.toByteArray();

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			GZIPOutputStream gzip = new GZIPOutputStream(out);
			gzip.write(imgBytes);
			gzip.close();
			byteArry = out.toString("utf8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return byteArry;
	}

	/**
	 * 根据Bitmap和尺寸，获取新的bitmap
	 * @param oldbmp
	 * @param w
	 * @param h
     * @return
     */
	public static Bitmap getNewBitmap(Bitmap oldbmp, int w, int h) {
		if (oldbmp != null) {
			int width = oldbmp.getWidth();
			int height = oldbmp.getHeight();
			Matrix matrix = new Matrix();
			float scaleWidth = ((float) w / width);
			float scaleHeight = ((float) h / height);
			matrix.postScale(scaleWidth, scaleHeight);
			Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
			return newbmp;
		} else {
			return null;
		}
	}

	/**
	 * 查看Android源码，Android提供了一种动态计算图片缩放比的方法,把它复制到这里
	 * @param options
	 * @param minSideLength
	 * @param maxNumOfPixels
	 * @return
	 */
	private static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}
		return roundedSize;
	}

	private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;
		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}
		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}
}
